#include "MuliThreadSave.h"
#include <iostream>

MuliThreadSave::MuliThreadSave(Client* _evtHandler)
{
    evtHandler=_evtHandler;
}

MuliThreadSave::~MuliThreadSave()
{}

std::string MuliThreadSave::StartSaveImage(std::string path,int32_t width,int32_t height,pixelFormat format)
{
    time_t nowTime=time(nullptr);
    struct tm* localTime=localtime(&nowTime);
    std::string fileName=fmt::format("R{}-{}-{}_{}_{}_{}.ccs",
        localTime->tm_year+1900,
        localTime->tm_mon+1,
        localTime->tm_mday,
        localTime->tm_hour,
        localTime->tm_min,
        localTime->tm_sec
    );
    fd=open((path+'/'+fileName).c_str(),O_WRONLY | O_CREAT | O_TRUNC,S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    if(fd==-1)
    {
      std::cout<<"can't save file,the path is: "<<path<<std::endl;
      throw std::exception();
    }
    frameCount=0;
    write(fd,&frameCount,sizeof(int32_t));
    write(fd,&width,sizeof(int32_t));
    write(fd,&height,sizeof(int32_t));
    write(fd,&format,sizeof(int32_t));
    imageSize=width*height;
    cmpThreadPool.reset(new CompressThread(3,imageSize,cmpAcc));
    threadExitFlag.store(false);
    ErrFlag.store(false);
    saveThread=std::thread(&MuliThreadSave::SaveImageFunc,this);
    std::cout<<"开始保存文件"<<std::endl;
    return fileName;
}

void MuliThreadSave::SaveImageFunc()
{
    while (!threadExitFlag.load())
    {
        unsigned char* data;
        int32_t size;
        int64_t time;
        try
        {
            cmpThreadPool->GetImageRes(data,size,time); //如果没有数据这里会堵塞
        }
        catch(...)
        {
            return;
        }
        write(fd,&time,sizeof(int64_t));
        write(fd,&size,sizeof(int32_t));
        ssize_t wSize=write(fd,data,size);
        if(wSize<0)
        {
            ErrFlag=true;
            evtHandler->sendErrorMessage("文件保存过程中出现异常");
            std::cout<<"文件保存过程中出现异常: "<<errno<<std::endl;
            return;
        }
        frameCount++;
        delete[] data;
    }
}

void MuliThreadSave::SaveImage(unsigned char* imageData,uint64_t timestamp)
{
    if(ErrFlag) 
      return;
    cmpThreadPool->PutImageTask(imageData,timestamp);
}

void MuliThreadSave::StopSaveImage()
{
    threadExitFlag=true;
    cmpThreadPool.reset(nullptr);
    if(saveThread.joinable())
        saveThread.join();
    lseek(fd,0,SEEK_SET);
    write(fd,&frameCount,sizeof(int32_t));
    fsync(fd);
    close(fd);
    fd=0;
    std::cout<<"文件采集停止"<<std::endl;
}

void MuliThreadSave::SetCmpAcceleration(int value)
{
    cmpAcc=value;
}
